package com.ruoyi.system.service.impl;

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.system.domain.SatelliteWeather;
import com.ruoyi.system.mapper.SatelliteWeatherMapper;
import com.ruoyi.system.service.ISatelliteWeatherService;

/**
 * 卫星气象数据Service业务层处理
 */
@Service
public class SatelliteWeatherServiceImpl implements ISatelliteWeatherService {

    @Value("${weather.api.key:demo}")
    private String weatherApiKey;

    @Value("${weather.api.url:https://api.openweathermap.org/data/2.5}")
    private String weatherApiUrl;

    @Autowired
    private SatelliteWeatherMapper satelliteWeatherMapper;

    @Override
    public SatelliteWeather selectSatelliteWeatherById(Long id) {
        return satelliteWeatherMapper.selectSatelliteWeatherById(id);
    }

    @Override
    public List<SatelliteWeather> selectSatelliteWeatherList(SatelliteWeather satelliteWeather) {
        return satelliteWeatherMapper.selectSatelliteWeatherList(satelliteWeather);
    }

    @Override
    public int insertSatelliteWeather(SatelliteWeather satelliteWeather) {
        satelliteWeather.setCreateTime(DateUtils.getNowDate());
        return satelliteWeatherMapper.insertSatelliteWeather(satelliteWeather);
    }

    @Override
    public int updateSatelliteWeather(SatelliteWeather satelliteWeather) {
        satelliteWeather.setUpdateTime(DateUtils.getNowDate());
        return satelliteWeatherMapper.updateSatelliteWeather(satelliteWeather);
    }

    @Override
    public int deleteSatelliteWeatherByIds(Long[] ids) {
        return satelliteWeatherMapper.deleteSatelliteWeatherByIds(ids);
    }

    @Override
    public int deleteSatelliteWeatherById(Long id) {
        return satelliteWeatherMapper.deleteSatelliteWeatherById(id);
    }

    @Override
    public Map<String, Object> getRealTimeWeather(String location) {
        try {
            // 首先尝试从数据库获取最新数据
            SatelliteWeather latestData = satelliteWeatherMapper.selectLatestWeatherByLocation(location);
            if (latestData != null && DateUtils.getNowDate().getTime() - latestData.getDataTime().getTime() < 3600000) {
                // 如果数据在1小时内，直接返回
                return convertToMap(latestData);
            }

            // 否则同步新数据
            boolean syncSuccess = syncSatelliteData(location);
            if (syncSuccess) {
                latestData = satelliteWeatherMapper.selectLatestWeatherByLocation(location);
                return convertToMap(latestData);
            } else {
                // 同步失败，返回模拟数据
                return generateMockWeatherData(location);
            }
        } catch (Exception e) {
            // 异常时返回模拟数据
            return generateMockWeatherData(location);
        }
    }

    @Override
    public List<Map<String, Object>> getDisasterAlerts() {
        List<Map<String, Object>> alerts = new ArrayList<>();

        // 模拟灾害预警数据
        String[] disasterTypes = {"暴雨", "干旱", "大风", "冰雹", "霜冻"};
        String[] riskLevels = {"低风险", "中风险", "高风险"};
        String[] locations = {"华北地区", "华东地区", "华南地区", "西南地区", "西北地区"};

        ThreadLocalRandom random = ThreadLocalRandom.current();

        for (int i = 0; i < 3; i++) {
            Map<String, Object> alert = new HashMap<>();
            alert.put("id", i + 1);
            alert.put("type", disasterTypes[random.nextInt(disasterTypes.length)]);
            alert.put("level", riskLevels[random.nextInt(riskLevels.length)]);
            alert.put("location", locations[random.nextInt(locations.length)]);
            alert.put("description", getDisasterDescription(alert.get("type").toString(), alert.get("level").toString()));
            alert.put("startTime", DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",
                    new Date(System.currentTimeMillis() + random.nextLong(86400000))));
            alert.put("endTime", DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",
                    new Date(System.currentTimeMillis() + random.nextLong(86400000, 172800000))));
            alert.put("advice", getDisasterAdvice(alert.get("type").toString()));

            alerts.add(alert);
        }

        return alerts;
    }

    @Override
    public boolean syncSatelliteData(String location) {
        try {
            // 这里调用公开气象API，由于需要API key，我们先用模拟数据
            // 实际使用时可以接入OpenWeatherMap、和风天气等

            SatelliteWeather weatherData = generateMockSatelliteData(location);
            satelliteWeatherMapper.insertSatelliteWeather(weatherData);
            return true;
        } catch (Exception e) {
            // 记录日志
            System.err.println("同步卫星数据失败: " + e.getMessage());
            return false;
        }
    }

    @Override
    public Map<String, Object> getWeatherStats(String location) {
        Map<String, Object> stats = new HashMap<>();

        // 模拟统计数据
        ThreadLocalRandom random = ThreadLocalRandom.current();

        stats.put("avgTemperature", random.nextInt(15, 30));
        stats.put("maxTemperature", random.nextInt(25, 35));
        stats.put("minTemperature", random.nextInt(5, 20));
        stats.put("totalRainfall", random.nextDouble(50, 300));
        stats.put("rainyDays", random.nextInt(5, 15));
        stats.put("windyDays", random.nextInt(10, 25));
        stats.put("disasterCount", random.nextInt(0, 5));

        return stats;
    }

    private Map<String, Object> convertToMap(SatelliteWeather data) {
        Map<String, Object> result = new HashMap<>();
        result.put("id", data.getId());
        result.put("location", data.getLocation());
        result.put("longitude", data.getLongitude());
        result.put("latitude", data.getLatitude());
        result.put("temperature", data.getTemperature());
        result.put("humidity", data.getHumidity());
        result.put("rainfall", data.getRainfall());
        result.put("windSpeed", data.getWindSpeed());
        result.put("windDirection", data.getWindDirection());
        result.put("pressure", data.getPressure());
        result.put("uvIndex", data.getUvIndex());
        result.put("aqi", data.getAqi());
        result.put("soilMoisture", data.getSoilMoisture());
        result.put("disasterRisk", data.getDisasterRisk());
        result.put("dataTime", data.getDataTime());
        result.put("dataSource", data.getDataSource());

        // 计算舒适度指数
        result.put("comfortIndex", calculateComfortIndex(data.getTemperature(), data.getHumidity()));

        return result;
    }

    private Map<String, Object> generateMockWeatherData(String location) {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        Map<String, Object> result = new HashMap<>();

        result.put("id", System.currentTimeMillis());
        result.put("location", location);
        result.put("longitude", 116.3974 + random.nextDouble(-0.5, 0.5));
        result.put("latitude", 39.9093 + random.nextDouble(-0.5, 0.5));
        result.put("temperature", random.nextDouble(15, 35));
        result.put("humidity", random.nextDouble(30, 90));
        result.put("rainfall", random.nextDouble(0, 50));
        result.put("windSpeed", random.nextDouble(0, 15));
        result.put("windDirection", getRandomWindDirection());
        result.put("pressure", random.nextDouble(980, 1030));
        result.put("uvIndex", random.nextInt(1, 11));
        result.put("aqi", random.nextInt(20, 150));
        result.put("soilMoisture", random.nextDouble(10, 80));
        result.put("disasterRisk", getRandomDisasterRisk());
        result.put("dataTime", new Date());
        result.put("dataSource", "模拟数据");
        result.put("comfortIndex", calculateComfortIndex(
                (Double) result.get("temperature"),
                (Double) result.get("humidity")
        ));

        return result;
    }

    private SatelliteWeather generateMockSatelliteData(String location) {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        SatelliteWeather data = new SatelliteWeather();

        data.setLocation(location);
        data.setLongitude(116.3974 + random.nextDouble(-0.5, 0.5));
        data.setLatitude(39.9093 + random.nextDouble(-0.5, 0.5));
        data.setTemperature(random.nextDouble(15, 35));
        data.setHumidity(random.nextDouble(30, 90));
        data.setRainfall(random.nextDouble(0, 50));
        data.setWindSpeed(random.nextDouble(0, 15));
        data.setWindDirection(getRandomWindDirection());
        data.setPressure(random.nextDouble(980, 1030));
        data.setUvIndex(random.nextInt(1, 11));
        data.setAqi(random.nextInt(20, 150));
        data.setSoilMoisture(random.nextDouble(10, 80));
        data.setDisasterRisk(getRandomDisasterRisk());
        data.setDataTime(new Date());
        data.setDataSource("卫星数据模拟");
        data.setCreateTime(new Date());

        return data;
    }

    private String getRandomWindDirection() {
        String[] directions = {"北风", "东北风", "东风", "东南风", "南风", "西南风", "西风", "西北风"};
        return directions[ThreadLocalRandom.current().nextInt(directions.length)];
    }

    private String getRandomDisasterRisk() {
        String[] risks = {"无", "低风险", "中风险", "高风险"};
        int random = ThreadLocalRandom.current().nextInt(100);
        if (random < 60) return "无";
        if (random < 80) return "低风险";
        if (random < 95) return "中风险";
        return "高风险";
    }

    private String calculateComfortIndex(double temperature, double humidity) {
        double index = temperature + 0.5 * humidity;
        if (index < 40) return "寒冷";
        if (index < 50) return "凉爽";
        if (index < 60) return "舒适";
        if (index < 70) return "温暖";
        return "炎热";
    }

    private String getDisasterDescription(String type, String level) {
        Map<String, String> descriptions = new HashMap<>();
        descriptions.put("暴雨", level + "暴雨预警，预计未来24小时内将有强降雨");
        descriptions.put("干旱", level + "干旱预警，土壤湿度严重不足");
        descriptions.put("大风", level + "大风预警，平均风力可达6级以上");
        descriptions.put("冰雹", level + "冰雹预警，可能对农作物造成损害");
        descriptions.put("霜冻", level + "霜冻预警，气温将降至0℃以下");
        return descriptions.getOrDefault(type, "气象灾害预警");
    }

    private String getDisasterAdvice(String type) {
        Map<String, String> advice = new HashMap<>();
        advice.put("暴雨", "建议暂停户外作业，注意排水防涝");
        advice.put("干旱", "建议及时灌溉，采取节水措施");
        advice.put("大风", "建议加固农业设施，暂停高空作业");
        advice.put("冰雹", "建议采取防护措施，保护农作物");
        advice.put("霜冻", "建议采取防冻措施，保护敏感作物");
        return advice.getOrDefault(type, "请密切关注天气变化，做好防范措施");
    }
}
